/****************************************************************************
 * Copyright (C) 2011
 * by Dimok
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you
 * must not claim that you wrote the original software. If you use
 * this software in a product, an acknowledgment in the product
 * documentation would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and
 * must not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 * distribution.
 ***************************************************************************/
#include "HomebrewBrowser.hpp"
#include "BootHomebrewTask.h"
#include "HomebrewXML.h"
#include "../Themes/CTheme.h"
#include "../TextOperations/wstring.hpp"
#include "../Prompts/HomebrewPrompt.hpp"
#include "../Prompts/PromptWindows.h"

HomebrewBrowser::HomebrewBrowser()
	: FlyingButtonsMenu()
{
	selectedItem = -1;
	
	buttonImgData = Resources::GetImageData("settings_title.png");
	buttonImgOverData = Resources::GetImageData("settings_title_over.png");
	
	for(u32 i = 0; i < 4; ++i)
	{
		IconImgData[i] = NULL;
		IconImg[i] = NULL;
	}

	HomebrewList = NULL;
	
	mainButtonDesc.clear();
	mainButtonDescOver.clear();

	SetupMainButtons();
}

HomebrewBrowser::~HomebrewBrowser()
{
	if(HomebrewList)
		delete HomebrewList;

	for(int i = 0; i < 4; ++i)
	{
		if(IconImgData[i])
			delete IconImgData[i];
		if(IconImg[i])
			delete IconImg[i];
		IconImgData[i] = NULL;
		IconImg[i] = NULL;
	}
	
	for(int i = 0; i < (int)mainButtonDesc.size(); ++i)
	{
		delete mainButtonDesc[i];
		delete mainButtonDescOver[i];
	}
	mainButtonDesc.clear();
	mainButtonDescOver.clear();
	
	Resources::Remove(buttonImgData);
	Resources::Remove(buttonImgOverData);
}

void HomebrewBrowser::HomebrewFilter()
{
	for(int i = 0; i < HomebrewList->GetFilecount(); i++)
	{
		if(strtokcmp(HomebrewList->GetFilename(i), "boot.dol,boot.elf", ",") != 0)
		{
			HomebrewList->RemoveEntrie(i);
			gprintf("\n\t HomebrewList(%i) removed", i);
			i--;
		}
	}
}

void HomebrewBrowser::SetupMainButtons()
{
	HomebrewList = new DirList(Settings.HomebrewPath, ".dol,.elf", DirList::Files | DirList::Dirs | DirList::CheckSubfolders);
	HomebrewFilter();
	if (!HomebrewList->GetFilecount())
	{
		ShowError(tr( "No homebrew found." ));
		return;
	}
	
	HomebrewXML MetaXML;

	for(int i = 0; i < HomebrewList->GetFilecount(); ++i)
	{
		std::string homebrewName = "";
		std::string homebrewDesc = "";
		std::string metaPath = HomebrewList->GetFilepath(i);
		size_t pos = metaPath.rfind('/');
		if(pos != std::string::npos && pos < metaPath.size()-1)
			metaPath.erase(pos+1);
		metaPath += "meta.xml";
		
		if (MetaXML.LoadHomebrewXMLData(metaPath.c_str()) > 0)
		{
			homebrewName = MetaXML.GetName();
			homebrewDesc = MetaXML.GetShortDescription();
		}
		else
		{
			const char * shortpath = HomebrewList->GetFilepath(i);
			const char * ptr = shortpath;
			const char * ptr2 = NULL;
			while(*ptr != '\0')
			{
				if(*ptr == '/')
				{
					shortpath = ptr2;
					ptr2 = ptr;
				}
				
				++ptr;
			}
			if(!shortpath && ptr2)
				shortpath = ptr2;
			else if(!shortpath)
				shortpath = HomebrewList->GetFilename(i);
			
			homebrewName = shortpath;
			homebrewDesc = " ";
		}
		
		GuiText * tmpTxt = new GuiText(homebrewDesc.c_str(), 18, thColor("r=0 g=0 b=0 a=255 - flyingbutton menu mainbutton text color"));
		tmpTxt->SetMaxWidth(buttonImgData->GetWidth() - 150, DOTTED);
		tmpTxt->SetAlignment(ALIGN_LEFT | ALIGN_MIDDLE);
		tmpTxt->SetPosition(148, 15);
		
		GuiText * tmpTxtOver = new GuiText(homebrewDesc.c_str(), 18, thColor("r=0 g=0 b=0 a=255 - flyingbutton menu mainbutton text color"));
		tmpTxtOver->SetMaxWidth(buttonImgData->GetWidth() - 150, SCROLL_HORIZONTAL);
		tmpTxtOver->SetAlignment(ALIGN_LEFT | ALIGN_MIDDLE);
		tmpTxtOver->SetPosition(148, 15);
		
		mainButtonDesc.push_back(tmpTxt);
		mainButtonDescOver.push_back(tmpTxtOver);
		
		SetMainButton(i, homebrewName, buttonImgData, buttonImgOverData);
		
		mainButtonTxt[i]->SetFontSize(18);
		mainButtonTxt[i]->SetMaxWidth(buttonImgData->GetWidth() - 150, DOTTED);
		mainButtonTxt[i]->SetAlignment(ALIGN_LEFT | ALIGN_MIDDLE);
		mainButtonTxt[i]->SetPosition(148, -12);
		mainButton[i]->SetLabel(mainButtonDesc[i], 1);
		mainButton[i]->SetLabelOver(mainButtonDescOver[i], 1);
	}
	
	SetPageIndicators();
}

void HomebrewBrowser::AddMainButtons()
{
	int i = 0;
	
	for(i = 0; i < (int) mainButton.size(); ++i)
	{
		Remove(mainButton[i]);
		mainButton[i]->SetIcon(NULL);
	}
	
	for(i = 0; i < 4; ++i)
	{
		if(IconImg[i])
			delete IconImg[i];
		if(IconImgData[i])
			delete IconImgData[i];
		IconImgData[i] = NULL;
		IconImg[i] = NULL;
	}
	
	int firstItem = currentPage*4;
	
	int n = 0;
	for(i = firstItem, n = 0; i < (int) mainButton.size() && i < firstItem+4; ++i, ++n)
	{
		std::string iconpath = HomebrewList->GetFilepath(i);
		size_t pos = iconpath.rfind('/');
		if(pos != std::string::npos && pos < iconpath.size()-1)
			iconpath.erase(pos+1);
		iconpath += "icon.png";
		
		IconImgData[n] = new GuiImageData(iconpath.c_str());
		IconImg[n] = new GuiImage(IconImgData[n]);
		IconImg[n]->SetAlignment(ALIGN_LEFT | ALIGN_MIDDLE);
		IconImg[n]->SetPosition(12, 0);
		IconImg[n]->SetScale(0.95);
		mainButton[i]->SetIcon(IconImg[n]);
		Append(mainButton[i]);
	}
	
	AddPageIndicators();
}

void HomebrewBrowser::OnMainButtonClick(GuiButton *sender, int pointer UNUSED, const POINT &p UNUSED)
{
	int index = -1;
	
	for(u32 i = 0; i < mainButton.size(); ++i)
	{
		if(sender != mainButton[i])
			continue;
		
		index = i;
		break;
	}
	
	if(index >= 0)
	{
		selectedItem = index;
		
		HomebrewXML MetaXML;
		
		std::string metaPath = HomebrewList->GetFilepath(index);
		size_t pos = metaPath.rfind('/');
		if(pos != std::string::npos && pos < metaPath.size()-1)
			metaPath.erase(pos+1);
		metaPath += "meta.xml";
		
		MetaXML.LoadHomebrewXMLData(metaPath.c_str());
		u64 filesize = HomebrewList->GetFilesize(index);
		wString HomebrewName(mainButtonTxt[index]->GetText());
		
		HomebrewPrompt * HBCWindowPrompt = new HomebrewPrompt(HomebrewName.toUTF8().c_str(),
															  MetaXML.GetCoder(),
															  MetaXML.GetVersion(),
															  MetaXML.GetReleasedate(),
															  MetaXML.GetLongDescription(),
															  IconImgData[index % 4],
															  filesize);
		
		HBCWindowPrompt->ButtonClicked.connect(this, &HomebrewBrowser::OnHBCWindowClick);
	}
}

void HomebrewBrowser::OnHBCWindowClick(PromptWindow * window UNUSED, int choice)
{
	if(choice)
	{
		std::string filepath = HomebrewList->GetFilepath(selectedItem);
		std::string filename = HomebrewList->GetFilename(selectedItem);
		std::string fileext = filepath;
		fileext = fileext.substr(fileext.find_last_of('.'));
		
		if(!fileext.compare(".dol"))
			choice = WindowPrompt(tr("Do you want to boot:"), filename.c_str(), tr("Wii Homebrew"), tr("GC Homebrew"), tr("Cancel"));
		else
			choice = WindowPrompt(tr("Do you want to boot:"), filename.c_str(), tr("Yes"), tr("No"));
		
		if(choice)
		{
			ClearArguments();
			AddBootArgument(filepath.c_str());
			
			BootHomebrewTask *task = new BootHomebrewTask(filepath, choice == 2);
			task->SetAutoRunOnLoadFinish(true);
		}
	}
}
